<!DOCTYPE html>
<html lang="" xml:lang="">
<head>

  <meta charset="utf-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <title>Chapter 23 Lena | JavaScript for R</title>
  <meta name="description" content="Invite JavaScript into your Data Science workflow." />
  <meta name="generator" content="bookdown 0.20 and GitBook 2.6.7" />

  <meta property="og:title" content="Chapter 23 Lena | JavaScript for R" />
  <meta property="og:type" content="book" />
  
  
  <meta property="og:description" content="Invite JavaScript into your Data Science workflow." />
  <meta name="github-repo" content="JohnCoene/javascript-for-r" />

  <meta name="twitter:card" content="summary" />
  <meta name="twitter:title" content="Chapter 23 Lena | JavaScript for R" />
  
  <meta name="twitter:description" content="Invite JavaScript into your Data Science workflow." />
  

<meta name="author" content="John Coene" />


<meta name="date" content="2020-08-23" />

  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <meta name="apple-mobile-web-app-capable" content="yes" />
  <meta name="apple-mobile-web-app-status-bar-style" content="black" />
  
  
<link rel="prev" href="machine-learning.html"/>
<link rel="next" href="conclusion.html"/>
<script src="libs/header-attrs/header-attrs.js"></script>
<script src="libs/jquery/jquery.min.js"></script>
<link href="libs/gitbook/css/style.css" rel="stylesheet" />
<link href="libs/gitbook/css/plugin-table.css" rel="stylesheet" />
<link href="libs/gitbook/css/plugin-bookdown.css" rel="stylesheet" />
<link href="libs/gitbook/css/plugin-highlight.css" rel="stylesheet" />
<link href="libs/gitbook/css/plugin-search.css" rel="stylesheet" />
<link href="libs/gitbook/css/plugin-fontsettings.css" rel="stylesheet" />
<link href="libs/gitbook/css/plugin-clipboard.css" rel="stylesheet" />









<script src="libs/accessible-code-block/empty-anchor.js"></script>
<script src="libs/htmlwidgets/htmlwidgets.js"></script>
<script src="libs/plotly-binding/plotly.js"></script>
<script src="libs/typedarray/typedarray.min.js"></script>
<link href="libs/crosstalk/css/crosstalk.css" rel="stylesheet" />
<script src="libs/crosstalk/js/crosstalk.min.js"></script>
<link href="libs/plotly-htmlwidgets-css/plotly-htmlwidgets.css" rel="stylesheet" />
<script src="libs/plotly-main/plotly-latest.min.js"></script>
<script src="libs/core-js/shim.min.js"></script>
<script src="libs/react/react.min.js"></script>
<script src="libs/react/react-dom.min.js"></script>
<script src="libs/reactwidget/react-tools.js"></script>
<script src="libs/reactable-binding/reactable.js"></script>
<script src="libs/r2d3-render/r2d3-render.js"></script>
<script src="libs/webcomponents/webcomponents.js"></script>
<script src="libs/r2d3-binding/r2d3.js"></script>
<script src="libs/d3v5/d3.min.js"></script>
<script src="libs/viz/viz.js"></script>
<link href="libs/DiagrammeR-styles/styles.css" rel="stylesheet" />
<script src="libs/grViz-binding/grViz.js"></script>


<style type="text/css">
pre > code.sourceCode { white-space: pre; position: relative; }
pre > code.sourceCode > span { display: inline-block; line-height: 1.25; }
pre > code.sourceCode > span:empty { height: 1.2em; }
code.sourceCode > span { color: inherit; text-decoration: inherit; }
pre.sourceCode { margin: 0; }
@media screen {
div.sourceCode { overflow: auto; }
}
@media print {
pre > code.sourceCode { white-space: pre-wrap; }
pre > code.sourceCode > span { text-indent: -5em; padding-left: 5em; }
}
pre.numberSource code
  { counter-reset: source-line 0; }
pre.numberSource code > span
  { position: relative; left: -4em; counter-increment: source-line; }
pre.numberSource code > span > a:first-child::before
  { content: counter(source-line);
    position: relative; left: -1em; text-align: right; vertical-align: baseline;
    border: none; display: inline-block;
    -webkit-touch-callout: none; -webkit-user-select: none;
    -khtml-user-select: none; -moz-user-select: none;
    -ms-user-select: none; user-select: none;
    padding: 0 4px; width: 4em;
    color: #aaaaaa;
  }
pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa;  padding-left: 4px; }
div.sourceCode
  {   }
@media screen {
pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; }
}
code span.al { color: #ff0000; font-weight: bold; } /* Alert */
code span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
code span.at { color: #7d9029; } /* Attribute */
code span.bn { color: #40a070; } /* BaseN */
code span.bu { } /* BuiltIn */
code span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
code span.ch { color: #4070a0; } /* Char */
code span.cn { color: #880000; } /* Constant */
code span.co { color: #60a0b0; font-style: italic; } /* Comment */
code span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
code span.do { color: #ba2121; font-style: italic; } /* Documentation */
code span.dt { color: #902000; } /* DataType */
code span.dv { color: #40a070; } /* DecVal */
code span.er { color: #ff0000; font-weight: bold; } /* Error */
code span.ex { } /* Extension */
code span.fl { color: #40a070; } /* Float */
code span.fu { color: #06287e; } /* Function */
code span.im { } /* Import */
code span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
code span.kw { color: #007020; font-weight: bold; } /* Keyword */
code span.op { color: #666666; } /* Operator */
code span.ot { color: #007020; } /* Other */
code span.pp { color: #bc7a00; } /* Preprocessor */
code span.sc { color: #4070a0; } /* SpecialChar */
code span.ss { color: #bb6688; } /* SpecialString */
code span.st { color: #4070a0; } /* String */
code span.va { color: #19177c; } /* Variable */
code span.vs { color: #4070a0; } /* VerbatimString */
code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
</style>

<link rel="stylesheet" href="css/style.css" type="text/css" />
<link rel="stylesheet" href="css/toc.css" type="text/css" />
</head>

<body>



  <div class="book without-animation with-summary font-size-2 font-family-1" data-basepath=".">

    <div class="book-summary">
      <nav role="navigation">

<ul class="summary">
<li><a href="./">JavaScript for R</a></li>

<li class="divider"></li>
<li class="chapter" data-level="" data-path="index.html"><a href="index.html"><i class="fa fa-check"></i>Preface</a>
<ul>
<li class="chapter" data-level="" data-path="index.html"><a href="index.html#premise"><i class="fa fa-check"></i>Premise</a></li>
<li class="chapter" data-level="" data-path="index.html"><a href="index.html#book-structure"><i class="fa fa-check"></i>Book Structure</a></li>
<li class="chapter" data-level="" data-path="index.html"><a href="index.html#acknowledgement"><i class="fa fa-check"></i>Acknowledgement</a></li>
<li class="chapter" data-level="" data-path="index.html"><a href="index.html#disclaimer"><i class="fa fa-check"></i>Disclaimer</a></li>
</ul></li>
<li class="part"><span><b>I Basics &amp; Roadmap</b></span></li>
<li class="chapter" data-level="1" data-path="introduction.html"><a href="introduction.html"><i class="fa fa-check"></i><b>1</b> Introduction</a>
<ul>
<li class="chapter" data-level="1.1" data-path="introduction.html"><a href="introduction.html#rationale"><i class="fa fa-check"></i><b>1.1</b> Rationale</a></li>
<li class="chapter" data-level="1.2" data-path="introduction.html"><a href="introduction.html#methods"><i class="fa fa-check"></i><b>1.2</b> Methods</a>
<ul>
<li class="chapter" data-level="1.2.1" data-path="introduction.html"><a href="introduction.html#v8"><i class="fa fa-check"></i><b>1.2.1</b> V8</a></li>
<li class="chapter" data-level="1.2.2" data-path="introduction.html"><a href="introduction.html#htmlwidgets"><i class="fa fa-check"></i><b>1.2.2</b> htmlwidgets</a></li>
<li class="chapter" data-level="1.2.3" data-path="introduction.html"><a href="introduction.html#shiny"><i class="fa fa-check"></i><b>1.2.3</b> Shiny</a></li>
<li class="chapter" data-level="1.2.4" data-path="introduction.html"><a href="introduction.html#bubble"><i class="fa fa-check"></i><b>1.2.4</b> bubble</a></li>
</ul></li>
<li class="chapter" data-level="1.3" data-path="introduction.html"><a href="introduction.html#methods-amiss"><i class="fa fa-check"></i><b>1.3</b> Methods Amiss</a>
<ul>
<li class="chapter" data-level="1.3.1" data-path="introduction.html"><a href="introduction.html#reactr"><i class="fa fa-check"></i><b>1.3.1</b> reactR</a></li>
<li class="chapter" data-level="1.3.2" data-path="introduction.html"><a href="introduction.html#r2d3"><i class="fa fa-check"></i><b>1.3.2</b> r2d3</a></li>
</ul></li>
</ul></li>
<li class="chapter" data-level="2" data-path="prerequisites.html"><a href="prerequisites.html"><i class="fa fa-check"></i><b>2</b> Prerequisites</a>
<ul>
<li class="chapter" data-level="2.1" data-path="prerequisites.html"><a href="prerequisites.html#r-package-development"><i class="fa fa-check"></i><b>2.1</b> R Package Development</a>
<ul>
<li class="chapter" data-level="2.1.1" data-path="prerequisites.html"><a href="prerequisites.html#creating-a-package"><i class="fa fa-check"></i><b>2.1.1</b> Creating a Package</a></li>
<li class="chapter" data-level="2.1.2" data-path="prerequisites.html"><a href="prerequisites.html#metadata"><i class="fa fa-check"></i><b>2.1.2</b> Metadata</a></li>
<li class="chapter" data-level="2.1.3" data-path="prerequisites.html"><a href="prerequisites.html#r-code"><i class="fa fa-check"></i><b>2.1.3</b> R code</a></li>
<li class="chapter" data-level="2.1.4" data-path="prerequisites.html"><a href="prerequisites.html#documentation"><i class="fa fa-check"></i><b>2.1.4</b> Documentation</a></li>
<li class="chapter" data-level="2.1.5" data-path="prerequisites.html"><a href="prerequisites.html#installed-files"><i class="fa fa-check"></i><b>2.1.5</b> Installed files</a></li>
<li class="chapter" data-level="2.1.6" data-path="prerequisites.html"><a href="prerequisites.html#build-load-and-install"><i class="fa fa-check"></i><b>2.1.6</b> Build, load, and install</a></li>
</ul></li>
<li class="chapter" data-level="2.2" data-path="prerequisites.html"><a href="prerequisites.html#json"><i class="fa fa-check"></i><b>2.2</b> JSON</a>
<ul>
<li class="chapter" data-level="2.2.1" data-path="prerequisites.html"><a href="prerequisites.html#serialising"><i class="fa fa-check"></i><b>2.2.1</b> Serialising</a></li>
<li class="chapter" data-level="2.2.2" data-path="prerequisites.html"><a href="prerequisites.html#tabular-data"><i class="fa fa-check"></i><b>2.2.2</b> Tabular data</a></li>
</ul></li>
<li class="chapter" data-level="2.3" data-path="prerequisites.html"><a href="prerequisites.html#javascript"><i class="fa fa-check"></i><b>2.3</b> JavaScript</a>
<ul>
<li class="chapter" data-level="2.3.1" data-path="prerequisites.html"><a href="prerequisites.html#developer-tools"><i class="fa fa-check"></i><b>2.3.1</b> Developer tools</a></li>
<li class="chapter" data-level="2.3.2" data-path="prerequisites.html"><a href="prerequisites.html#variable-declaration-and-scope"><i class="fa fa-check"></i><b>2.3.2</b> Variable declaration and scope</a></li>
<li class="chapter" data-level="2.3.3" data-path="prerequisites.html"><a href="prerequisites.html#document-object-model"><i class="fa fa-check"></i><b>2.3.3</b> Document object model</a></li>
</ul></li>
</ul></li>
<li class="part"><span><b>II Data Visualisation</b></span></li>
<li class="chapter" data-level="3" data-path="introduction-to-widgets.html"><a href="introduction-to-widgets.html"><i class="fa fa-check"></i><b>3</b> Introduction to widgets</a>
<ul>
<li class="chapter" data-level="3.1" data-path="introduction-to-widgets.html"><a href="introduction-to-widgets.html#plotly-package"><i class="fa fa-check"></i><b>3.1</b> Plotly package</a></li>
<li class="chapter" data-level="3.2" data-path="introduction-to-widgets.html"><a href="introduction-to-widgets.html#dt-package"><i class="fa fa-check"></i><b>3.2</b> DT package</a></li>
</ul></li>
<li class="chapter" data-level="4" data-path="basics-of-building-widgets.html"><a href="basics-of-building-widgets.html"><i class="fa fa-check"></i><b>4</b> Basics of building widgets</a>
<ul>
<li class="chapter" data-level="4.1" data-path="basics-of-building-widgets.html"><a href="basics-of-building-widgets.html#candidate-libraries"><i class="fa fa-check"></i><b>4.1</b> Candidate Libraries</a>
<ul>
<li class="chapter" data-level="4.1.1" data-path="basics-of-building-widgets.html"><a href="basics-of-building-widgets.html#plotly"><i class="fa fa-check"></i><b>4.1.1</b> Plotly</a></li>
<li class="chapter" data-level="4.1.2" data-path="basics-of-building-widgets.html"><a href="basics-of-building-widgets.html#highchart.js"><i class="fa fa-check"></i><b>4.1.2</b> Highchart.js</a></li>
<li class="chapter" data-level="4.1.3" data-path="basics-of-building-widgets.html"><a href="basics-of-building-widgets.html#chart.js"><i class="fa fa-check"></i><b>4.1.3</b> Chart.js</a></li>
</ul></li>
<li class="chapter" data-level="4.2" data-path="basics-of-building-widgets.html"><a href="basics-of-building-widgets.html#how-it-works"><i class="fa fa-check"></i><b>4.2</b> How it works</a></li>
</ul></li>
<li class="chapter" data-level="5" data-path="your-first-widget.html"><a href="your-first-widget.html"><i class="fa fa-check"></i><b>5</b> Your First Widget</a>
<ul>
<li class="chapter" data-level="5.1" data-path="your-first-widget.html"><a href="your-first-widget.html#the-scaffold"><i class="fa fa-check"></i><b>5.1</b> The Scaffold</a></li>
<li class="chapter" data-level="5.2" data-path="your-first-widget.html"><a href="your-first-widget.html#the-output"><i class="fa fa-check"></i><b>5.2</b> The Output</a></li>
<li class="chapter" data-level="5.3" data-path="your-first-widget.html"><a href="your-first-widget.html#javascript-side"><i class="fa fa-check"></i><b>5.3</b> JavaScript-side</a></li>
</ul></li>
<li class="chapter" data-level="6" data-path="a-realistic-widget.html"><a href="a-realistic-widget.html"><i class="fa fa-check"></i><b>6</b> A Realistic Widget</a>
<ul>
<li class="chapter" data-level="6.1" data-path="a-realistic-widget.html"><a href="a-realistic-widget.html#dependency"><i class="fa fa-check"></i><b>6.1</b> Dependency</a></li>
<li class="chapter" data-level="6.2" data-path="prerequisites.html"><a href="prerequisites.html#javascript"><i class="fa fa-check"></i><b>6.2</b> JavaScript</a></li>
<li class="chapter" data-level="6.3" data-path="a-realistic-widget.html"><a href="a-realistic-widget.html#html-element"><i class="fa fa-check"></i><b>6.3</b> HTML Element</a></li>
</ul></li>
<li class="chapter" data-level="7" data-path="the-full-monty.html"><a href="the-full-monty.html"><i class="fa fa-check"></i><b>7</b> The Full Monty</a>
<ul>
<li class="chapter" data-level="7.1" data-path="the-full-monty.html"><a href="the-full-monty.html#dependencies"><i class="fa fa-check"></i><b>7.1</b> Dependencies</a></li>
<li class="chapter" data-level="7.2" data-path="prerequisites.html"><a href="prerequisites.html#javascript"><i class="fa fa-check"></i><b>7.2</b> JavaScript</a></li>
<li class="chapter" data-level="7.3" data-path="the-full-monty.html"><a href="the-full-monty.html#working-with-data"><i class="fa fa-check"></i><b>7.3</b> Working with Data</a></li>
<li class="chapter" data-level="7.4" data-path="the-full-monty.html"><a href="the-full-monty.html#transforming-data"><i class="fa fa-check"></i><b>7.4</b> Transforming Data</a>
<ul>
<li class="chapter" data-level="7.4.1" data-path="the-full-monty.html"><a href="the-full-monty.html#in-javascript"><i class="fa fa-check"></i><b>7.4.1</b> In JavaScript</a></li>
<li class="chapter" data-level="7.4.2" data-path="the-full-monty.html"><a href="the-full-monty.html#in-r"><i class="fa fa-check"></i><b>7.4.2</b> In R</a></li>
<li class="chapter" data-level="7.4.3" data-path="the-full-monty.html"><a href="the-full-monty.html#pros-cons"><i class="fa fa-check"></i><b>7.4.3</b> Pros &amp; Cons</a></li>
</ul></li>
<li class="chapter" data-level="7.5" data-path="the-full-monty.html"><a href="the-full-monty.html#on-print"><i class="fa fa-check"></i><b>7.5</b> On Print</a></li>
</ul></li>
<li class="chapter" data-level="8" data-path="advanced-topics.html"><a href="advanced-topics.html"><i class="fa fa-check"></i><b>8</b> Advanced Topics</a>
<ul>
<li class="chapter" data-level="8.1" data-path="advanced-topics.html"><a href="advanced-topics.html#shared-variables"><i class="fa fa-check"></i><b>8.1</b> Shared Variables</a>
<ul>
<li class="chapter" data-level="8.1.1" data-path="advanced-topics.html"><a href="advanced-topics.html#sizing"><i class="fa fa-check"></i><b>8.1.1</b> Sizing</a></li>
<li class="chapter" data-level="8.1.2" data-path="advanced-topics.html"><a href="advanced-topics.html#sizing-policy"><i class="fa fa-check"></i><b>8.1.2</b> Sizing Policy</a></li>
</ul></li>
<li class="chapter" data-level="8.2" data-path="advanced-topics.html"><a href="advanced-topics.html#resizing"><i class="fa fa-check"></i><b>8.2</b> Resizing</a></li>
<li class="chapter" data-level="8.3" data-path="advanced-topics.html"><a href="advanced-topics.html#pre-render-hooks-security"><i class="fa fa-check"></i><b>8.3</b> Pre Render Hooks &amp; Security</a></li>
<li class="chapter" data-level="8.4" data-path="advanced-topics.html"><a href="advanced-topics.html#javascript-code"><i class="fa fa-check"></i><b>8.4</b> JavaScript Code</a></li>
<li class="chapter" data-level="8.5" data-path="advanced-topics.html"><a href="advanced-topics.html#prepend-append-content"><i class="fa fa-check"></i><b>8.5</b> Prepend &amp; Append Content</a></li>
<li class="chapter" data-level="8.6" data-path="the-full-monty.html"><a href="the-full-monty.html#dependencies"><i class="fa fa-check"></i><b>8.6</b> Dependencies</a></li>
<li class="chapter" data-level="8.7" data-path="advanced-topics.html"><a href="advanced-topics.html#compatibility"><i class="fa fa-check"></i><b>8.7</b> Compatibility</a></li>
<li class="chapter" data-level="8.8" data-path="advanced-topics.html"><a href="advanced-topics.html#unit-tests"><i class="fa fa-check"></i><b>8.8</b> Unit Tests</a></li>
<li class="chapter" data-level="8.9" data-path="advanced-topics.html"><a href="advanced-topics.html#performances"><i class="fa fa-check"></i><b>8.9</b> Performances</a></li>
</ul></li>
<li class="chapter" data-level="9" data-path="crosstalk.html"><a href="crosstalk.html"><i class="fa fa-check"></i><b>9</b> Crosstalk</a>
<ul>
<li class="chapter" data-level="9.1" data-path="crosstalk.html"><a href="crosstalk.html#crosstalk-example"><i class="fa fa-check"></i><b>9.1</b> Crosstalk example</a></li>
<li class="chapter" data-level="9.2" data-path="crosstalk.html"><a href="crosstalk.html#crosstalk-requirements"><i class="fa fa-check"></i><b>9.2</b> Crosstalk requirements</a></li>
<li class="chapter" data-level="9.3" data-path="basics-of-building-widgets.html"><a href="basics-of-building-widgets.html#how-it-works"><i class="fa fa-check"></i><b>9.3</b> How it works</a></li>
<li class="chapter" data-level="9.4" data-path="crosstalk.html"><a href="crosstalk.html#crosstalk-with-gio"><i class="fa fa-check"></i><b>9.4</b> Crosstalk with gio</a></li>
<li class="chapter" data-level="9.5" data-path="crosstalk.html"><a href="crosstalk.html#adapt-the-r-code"><i class="fa fa-check"></i><b>9.5</b> Adapt the R code</a></li>
<li class="chapter" data-level="9.6" data-path="crosstalk.html"><a href="crosstalk.html#change-the-javascript-code"><i class="fa fa-check"></i><b>9.6</b> Change the JavaScript code</a>
<ul>
<li class="chapter" data-level="9.6.1" data-path="crosstalk.html"><a href="crosstalk.html#send-selected-keys"><i class="fa fa-check"></i><b>9.6.1</b> Send selected keys</a></li>
<li class="chapter" data-level="9.6.2" data-path="crosstalk.html"><a href="crosstalk.html#set-selected-keys"><i class="fa fa-check"></i><b>9.6.2</b> Set selected keys</a></li>
<li class="chapter" data-level="9.6.3" data-path="crosstalk.html"><a href="crosstalk.html#using-crosstalk-with-gio"><i class="fa fa-check"></i><b>9.6.3</b> Using crosstalk with gio</a></li>
</ul></li>
</ul></li>
<li class="chapter" data-level="10" data-path="final-revisions.html"><a href="final-revisions.html"><i class="fa fa-check"></i><b>10</b> Final Revisions</a>
<ul>
<li class="chapter" data-level="10.1" data-path="the-full-monty.html"><a href="the-full-monty.html#working-with-data"><i class="fa fa-check"></i><b>10.1</b> Working with data</a></li>
<li class="chapter" data-level="10.2" data-path="final-revisions.html"><a href="final-revisions.html#plethora-of-options"><i class="fa fa-check"></i><b>10.2</b> Plethora of options</a></li>
<li class="chapter" data-level="10.3" data-path="final-revisions.html"><a href="final-revisions.html#interface-design"><i class="fa fa-check"></i><b>10.3</b> Interface design</a></li>
</ul></li>
<li class="chapter" data-level="11" data-path="excercise-ploty.html"><a href="excercise-ploty.html"><i class="fa fa-check"></i><b>11</b> Excercise - Ploty</a>
<ul>
<li class="chapter" data-level="11.1" data-path="excercise-ploty.html"><a href="excercise-ploty.html#discover"><i class="fa fa-check"></i><b>11.1</b> Discover</a></li>
<li class="chapter" data-level="11.2" data-path="excercise-ploty.html"><a href="excercise-ploty.html#basics"><i class="fa fa-check"></i><b>11.2</b> Basics</a></li>
<li class="chapter" data-level="11.3" data-path="excercise-ploty.html"><a href="excercise-ploty.html#javascript-to-r"><i class="fa fa-check"></i><b>11.3</b> JavaScript to R</a></li>
<li class="chapter" data-level="11.4" data-path="excercise-ploty.html"><a href="excercise-ploty.html#r-to-javascript"><i class="fa fa-check"></i><b>11.4</b> R to JavaScript</a></li>
<li class="chapter" data-level="11.5" data-path="excercise-ploty.html"><a href="excercise-ploty.html#size-resize"><i class="fa fa-check"></i><b>11.5</b> Size &amp; Resize</a></li>
<li class="chapter" data-level="11.6" data-path="excercise-ploty.html"><a href="excercise-ploty.html#performance-security"><i class="fa fa-check"></i><b>11.6</b> Performance &amp; Security</a></li>
</ul></li>
<li class="part"><span><b>III Web Development with Shiny</b></span></li>
<li class="chapter" data-level="12" data-path="excercise-ploty.html"><a href="excercise-ploty.html#discover"><i class="fa fa-check"></i><b>12</b> Discover</a>
<ul>
<li class="chapter" data-level="12.1" data-path="discover.html"><a href="discover.html"><i class="fa fa-check"></i><b>12.1</b> Static Files</a></li>
<li class="chapter" data-level="12.2" data-path="discover.html"><a href="discover.html#example---alerts"><i class="fa fa-check"></i><b>12.2</b> Example - Alerts</a></li>
<li class="chapter" data-level="12.3" data-path="discover.html"><a href="discover.html#from-r-to-javascript"><i class="fa fa-check"></i><b>12.3</b> From R to JavaScript</a></li>
<li class="chapter" data-level="12.4" data-path="discover.html"><a href="discover.html#from-javascript-to-r"><i class="fa fa-check"></i><b>12.4</b> From JavaScript to R</a></li>
<li class="chapter" data-level="12.5" data-path="discover.html"><a href="discover.html#deserialise"><i class="fa fa-check"></i><b>12.5</b> Deserialise</a></li>
</ul></li>
<li class="chapter" data-level="13" data-path="a-complete-integration.html"><a href="a-complete-integration.html"><i class="fa fa-check"></i><b>13</b> A Complete Integration</a>
<ul>
<li class="chapter" data-level="13.1" data-path="a-complete-integration.html"><a href="a-complete-integration.html#serialisation"><i class="fa fa-check"></i><b>13.1</b> Serialisation</a></li>
<li class="chapter" data-level="13.2" data-path="a-complete-integration.html"><a href="a-complete-integration.html#events-callbacks"><i class="fa fa-check"></i><b>13.2</b> Events &amp; Callbacks</a></li>
<li class="chapter" data-level="13.3" data-path="a-complete-integration.html"><a href="a-complete-integration.html#as-a-package"><i class="fa fa-check"></i><b>13.3</b> As a Package</a>
<ul>
<li class="chapter" data-level="13.3.1" data-path="the-full-monty.html"><a href="the-full-monty.html#dependencies"><i class="fa fa-check"></i><b>13.3.1</b> Dependencies</a></li>
<li class="chapter" data-level="13.3.2" data-path="prerequisites.html"><a href="prerequisites.html#r-code"><i class="fa fa-check"></i><b>13.3.2</b> R Code</a></li>
<li class="chapter" data-level="13.3.3" data-path="advanced-topics.html"><a href="advanced-topics.html#javascript-code"><i class="fa fa-check"></i><b>13.3.3</b> JavaScript Code</a></li>
<li class="chapter" data-level="13.3.4" data-path="a-complete-integration.html"><a href="a-complete-integration.html#input-handler"><i class="fa fa-check"></i><b>13.3.4</b> Input Handler</a></li>
<li class="chapter" data-level="13.3.5" data-path="a-complete-integration.html"><a href="a-complete-integration.html#wrapping-up"><i class="fa fa-check"></i><b>13.3.5</b> Wrapping up</a></li>
</ul></li>
</ul></li>
<li class="chapter" data-level="14" data-path="tips-tricks.html"><a href="tips-tricks.html"><i class="fa fa-check"></i><b>14</b> Tips &amp; Tricks</a>
<ul>
<li class="chapter" data-level="14.1" data-path="tips-tricks.html"><a href="tips-tricks.html#shiny-events"><i class="fa fa-check"></i><b>14.1</b> Shiny Events</a></li>
<li class="chapter" data-level="14.2" data-path="tips-tricks.html"><a href="tips-tricks.html#table-buttons"><i class="fa fa-check"></i><b>14.2</b> Table Buttons</a></li>
<li class="chapter" data-level="14.3" data-path="tips-tricks.html"><a href="tips-tricks.html#jquery---toggle"><i class="fa fa-check"></i><b>14.3</b> jQuery - Toggle</a></li>
</ul></li>
<li class="chapter" data-level="15" data-path="custom-outputs.html"><a href="custom-outputs.html"><i class="fa fa-check"></i><b>15</b> Custom Outputs</a>
<ul>
<li class="chapter" data-level="15.1" data-path="custom-outputs.html"><a href="custom-outputs.html#custom-outputs-inner-workings"><i class="fa fa-check"></i><b>15.1</b> Custom outputs inner-workings</a></li>
<li class="chapter" data-level="15.2" data-path="custom-outputs.html"><a href="custom-outputs.html#setup"><i class="fa fa-check"></i><b>15.2</b> Setup</a></li>
<li class="chapter" data-level="15.3" data-path="custom-outputs.html"><a href="custom-outputs.html#r-function"><i class="fa fa-check"></i><b>15.3</b> R function</a></li>
<li class="chapter" data-level="15.4" data-path="custom-outputs.html"><a href="custom-outputs.html#output"><i class="fa fa-check"></i><b>15.4</b> Output</a></li>
<li class="chapter" data-level="15.5" data-path="custom-outputs.html"><a href="custom-outputs.html#render"><i class="fa fa-check"></i><b>15.5</b> Render</a></li>
<li class="chapter" data-level="15.6" data-path="custom-outputs.html"><a href="custom-outputs.html#javascript-output-binding"><i class="fa fa-check"></i><b>15.6</b> JavaScript output binding</a>
<ul>
<li class="chapter" data-level="15.6.1" data-path="custom-outputs.html"><a href="custom-outputs.html#boxxy-title"><i class="fa fa-check"></i><b>15.6.1</b> Boxxy title</a></li>
<li class="chapter" data-level="15.6.2" data-path="custom-outputs.html"><a href="custom-outputs.html#boxxy-value"><i class="fa fa-check"></i><b>15.6.2</b> Boxxy value</a></li>
</ul></li>
<li class="chapter" data-level="15.7" data-path="custom-outputs.html"><a href="custom-outputs.html#boxxy-background-color"><i class="fa fa-check"></i><b>15.7</b> Boxxy background color</a>
<ul>
<li class="chapter" data-level="15.7.1" data-path="custom-outputs.html"><a href="custom-outputs.html#register-the-binding"><i class="fa fa-check"></i><b>15.7.1</b> Register the binding</a></li>
</ul></li>
<li class="chapter" data-level="15.8" data-path="custom-outputs.html"><a href="custom-outputs.html#boxxy-usage"><i class="fa fa-check"></i><b>15.8</b> Boxxy usage</a></li>
</ul></li>
<li class="chapter" data-level="16" data-path="cookies.html"><a href="cookies.html"><i class="fa fa-check"></i><b>16</b> Cookies</a>
<ul>
<li class="chapter" data-level="16.1" data-path="cookies.html"><a href="cookies.html#discover-js-cookie"><i class="fa fa-check"></i><b>16.1</b> Discover js-cookie</a></li>
<li class="chapter" data-level="16.2" data-path="custom-outputs.html"><a href="custom-outputs.html#setup"><i class="fa fa-check"></i><b>16.2</b> Setup</a></li>
<li class="chapter" data-level="16.3" data-path="prerequisites.html"><a href="prerequisites.html#javascript"><i class="fa fa-check"></i><b>16.3</b> JavaScript</a></li>
<li class="chapter" data-level="16.4" data-path="prerequisites.html"><a href="prerequisites.html#r-code"><i class="fa fa-check"></i><b>16.4</b> R Code</a></li>
</ul></li>
<li class="chapter" data-level="17" data-path="widgets-with-shiny.html"><a href="widgets-with-shiny.html"><i class="fa fa-check"></i><b>17</b> Widgets with Shiny</a>
<ul>
<li class="chapter" data-level="17.1" data-path="excercise-ploty.html"><a href="excercise-ploty.html#javascript-to-r"><i class="fa fa-check"></i><b>17.1</b> JavaScript to R</a></li>
<li class="chapter" data-level="17.2" data-path="a-complete-integration.html"><a href="a-complete-integration.html#input-handler"><i class="fa fa-check"></i><b>17.2</b> Input Handler</a></li>
<li class="chapter" data-level="17.3" data-path="excercise-ploty.html"><a href="excercise-ploty.html#r-to-javascript"><i class="fa fa-check"></i><b>17.3</b> R to JavaScript</a>
<ul>
<li class="chapter" data-level="17.3.1" data-path="widgets-with-shiny.html"><a href="widgets-with-shiny.html#send-data"><i class="fa fa-check"></i><b>17.3.1</b> Send Data</a></li>
<li class="chapter" data-level="17.3.2" data-path="widgets-with-shiny.html"><a href="widgets-with-shiny.html#retrieve-widget-instance"><i class="fa fa-check"></i><b>17.3.2</b> Retrieve Widget Instance</a></li>
<li class="chapter" data-level="17.3.3" data-path="widgets-with-shiny.html"><a href="widgets-with-shiny.html#handle-data"><i class="fa fa-check"></i><b>17.3.3</b> Handle Data</a></li>
</ul></li>
<li class="chapter" data-level="17.4" data-path="widgets-with-shiny.html"><a href="widgets-with-shiny.html#proxy-function"><i class="fa fa-check"></i><b>17.4</b> Proxy Function</a></li>
<li class="chapter" data-level="17.5" data-path="widgets-with-shiny.html"><a href="widgets-with-shiny.html#clear-data"><i class="fa fa-check"></i><b>17.5</b> Clear Data</a></li>
<li class="chapter" data-level="17.6" data-path="widgets-with-shiny.html"><a href="widgets-with-shiny.html#update"><i class="fa fa-check"></i><b>17.6</b> Update</a></li>
</ul></li>
<li class="part"><span><b>IV JavaScript for Computations</b></span></li>
<li class="chapter" data-level="18" data-path="the-v8-engine.html"><a href="the-v8-engine.html"><i class="fa fa-check"></i><b>18</b> The V8 Engine</a>
<ul>
<li class="chapter" data-level="18.1" data-path="the-v8-engine.html"><a href="the-v8-engine.html#installation"><i class="fa fa-check"></i><b>18.1</b> Installation</a></li>
<li class="chapter" data-level="18.2" data-path="excercise-ploty.html"><a href="excercise-ploty.html#basics"><i class="fa fa-check"></i><b>18.2</b> Basics</a></li>
<li class="chapter" data-level="18.3" data-path="the-v8-engine.html"><a href="the-v8-engine.html#external-libraries"><i class="fa fa-check"></i><b>18.3</b> External Libraries</a></li>
<li class="chapter" data-level="18.4" data-path="the-v8-engine.html"><a href="the-v8-engine.html#with-npm"><i class="fa fa-check"></i><b>18.4</b> With Npm</a></li>
<li class="chapter" data-level="18.5" data-path="the-v8-engine.html"><a href="the-v8-engine.html#use-in-packages"><i class="fa fa-check"></i><b>18.5</b> Use in Packages</a></li>
</ul></li>
<li class="chapter" data-level="19" data-path="node.html"><a href="node.html"><i class="fa fa-check"></i><b>19</b> Node.js with Bubble</a>
<ul>
<li class="chapter" data-level="19.1" data-path="excercise-ploty.html"><a href="excercise-ploty.html#basics"><i class="fa fa-check"></i><b>19.1</b> Basics</a></li>
<li class="chapter" data-level="19.2" data-path="node.html"><a href="node.html#r-markdown-engine"><i class="fa fa-check"></i><b>19.2</b> R Markdown Engine</a></li>
<li class="chapter" data-level="19.3" data-path="node.html"><a href="node.html#npm"><i class="fa fa-check"></i><b>19.3</b> Npm</a></li>
</ul></li>
<li class="part"><span><b>V Examples</b></span></li>
<li class="chapter" data-level="20" data-path="image-classifier.html"><a href="image-classifier.html"><i class="fa fa-check"></i><b>20</b> Image Classifier</a>
<ul>
<li class="chapter" data-level="20.1" data-path="excercise-ploty.html"><a href="excercise-ploty.html#discover"><i class="fa fa-check"></i><b>20.1</b> Discover</a></li>
<li class="chapter" data-level="20.2" data-path="custom-outputs.html"><a href="custom-outputs.html#setup"><i class="fa fa-check"></i><b>20.2</b> Setup</a></li>
<li class="chapter" data-level="20.3" data-path="prerequisites.html"><a href="prerequisites.html#javascript"><i class="fa fa-check"></i><b>20.3</b> JavaScript</a></li>
<li class="chapter" data-level="20.4" data-path="a-complete-integration.html"><a href="a-complete-integration.html#input-handler"><i class="fa fa-check"></i><b>20.4</b> Input Handler</a></li>
</ul></li>
<li class="chapter" data-level="21" data-path="progress-bar.html"><a href="progress-bar.html"><i class="fa fa-check"></i><b>21</b> Progress Bar</a>
<ul>
<li class="chapter" data-level="21.1" data-path="prerequisites.html"><a href="prerequisites.html#r-code"><i class="fa fa-check"></i><b>21.1</b> R code</a></li>
<li class="chapter" data-level="21.2" data-path="advanced-topics.html"><a href="advanced-topics.html#javascript-code"><i class="fa fa-check"></i><b>21.2</b> JavaScript code</a></li>
<li class="chapter" data-level="21.3" data-path="progress-bar.html"><a href="progress-bar.html#events"><i class="fa fa-check"></i><b>21.3</b> Events</a></li>
</ul></li>
<li class="chapter" data-level="22" data-path="machine-learning.html"><a href="machine-learning.html"><i class="fa fa-check"></i><b>22</b> Machine Learning</a>
<ul>
<li class="chapter" data-level="22.1" data-path="a-realistic-widget.html"><a href="a-realistic-widget.html#dependency"><i class="fa fa-check"></i><b>22.1</b> Dependency</a></li>
<li class="chapter" data-level="22.2" data-path="machine-learning.html"><a href="machine-learning.html#simple-regression"><i class="fa fa-check"></i><b>22.2</b> Simple Regression</a></li>
</ul></li>
<li class="chapter" data-level="23" data-path="lena.html"><a href="lena.html"><i class="fa fa-check"></i><b>23</b> Lena</a>
<ul>
<li class="chapter" data-level="23.1" data-path="lena.html"><a href="lena.html#inner-workings"><i class="fa fa-check"></i><b>23.1</b> Inner-workings</a></li>
<li class="chapter" data-level="23.2" data-path="lena.html"><a href="lena.html#discover-lena.js"><i class="fa fa-check"></i><b>23.2</b> Discover Lena.js</a></li>
<li class="chapter" data-level="23.3" data-path="custom-outputs.html"><a href="custom-outputs.html#setup"><i class="fa fa-check"></i><b>23.3</b> Setup</a></li>
<li class="chapter" data-level="23.4" data-path="custom-outputs.html"><a href="custom-outputs.html#output"><i class="fa fa-check"></i><b>23.4</b> Output</a></li>
<li class="chapter" data-level="23.5" data-path="custom-outputs.html"><a href="custom-outputs.html#render"><i class="fa fa-check"></i><b>23.5</b> Render</a></li>
<li class="chapter" data-level="23.6" data-path="lena.html"><a href="lena.html#javascript-binding"><i class="fa fa-check"></i><b>23.6</b> JavaScript Binding</a></li>
<li class="chapter" data-level="23.7" data-path="lena.html"><a href="lena.html#test"><i class="fa fa-check"></i><b>23.7</b> Test</a></li>
</ul></li>
<li class="part"><span><b>VI Closing Remarks</b></span></li>
<li class="chapter" data-level="24" data-path="conclusion.html"><a href="conclusion.html"><i class="fa fa-check"></i><b>24</b> Conclusion</a>
<ul>
<li class="chapter" data-level="24.1" data-path="advanced-topics.html"><a href="advanced-topics.html#performances"><i class="fa fa-check"></i><b>24.1</b> Performances</a></li>
<li class="chapter" data-level="24.2" data-path="conclusion.html"><a href="conclusion.html#road-ahead"><i class="fa fa-check"></i><b>24.2</b> Road ahead</a>
<ul>
<li class="chapter" data-level="24.2.1" data-path="conclusion.html"><a href="conclusion.html#computation"><i class="fa fa-check"></i><b>24.2.1</b> Computation</a></li>
<li class="chapter" data-level="24.2.2" data-path="introduction.html"><a href="introduction.html#shiny"><i class="fa fa-check"></i><b>24.2.2</b> Shiny</a></li>
<li class="chapter" data-level="24.2.3" data-path="introduction.html"><a href="introduction.html#htmlwidgets"><i class="fa fa-check"></i><b>24.2.3</b> htmlwidgets</a></li>
</ul></li>
</ul></li>
<li class="chapter" data-level="" data-path="references.html"><a href="references.html"><i class="fa fa-check"></i>References</a></li>
</ul>

      </nav>
    </div>

    <div class="book-body">
      <div class="body-inner">
        <div class="book-header" role="navigation">
          <h1>
            <i class="fa fa-circle-o-notch fa-spin"></i><a href="./">JavaScript for R</a>
          </h1>
        </div>

        <div class="page-wrapper" tabindex="-1" role="main">
          <div class="page-inner">

            <section class="normal" id="section-">
<div id="lena" class="section level1" number="23">
<h1><span class="header-section-number">Chapter 23</span> Lena</h1>
<p>In this chapter we create a custom shiny output, in practical terms, custom <code>render*</code> and <code>*Output</code> functions to use in Shiny. Note that this is destined for the curious who want to grasp some understanding of how these functions work under the hood as it is <em>often easier to create an htmlwidgets package.</em>
We will demonstrate by creating a wrapper for <a href="https://github.com/davidsonfellipe/lena.js">lena.js</a>, a JavaScript library to apply filters to images. Note that this is just for the purpose of demonstrating how to create custom outputs, there are much easier ways to apply such filters ina shiny application (e.g.: CSS).</p>
<div id="inner-workings" class="section level2" number="23.1">
<h2><span class="header-section-number">23.1</span> Inner-workings</h2>
<p>At the core, this consists in creating a <code>lena</code>, <code>renderLena</code> and <code>lenaOutput</code> functions (analogous to <code>plot</code>, <code>renderPlot</code>, <code>plotOutput</code>) which are linked by an “output binding” in JavaScript. The latter function essentially creates an HTML element (e.g.: <code>&lt;div&gt;</code>) with its dependencies attached, the former <code>render*</code> rather straightforward, unlike previous examples, the data does not need to be explicitly sent to the front-end using <code>session$sendCustomMessage</code> as this is handled by shiny itself under the hood.</p>
<p>Previous work with shiny and JavaScript covered in this book had no dedicated “output” element that were placed in the shiny UI, therefore one had to use a function solely dedicated to importing the dependencies (e.g.: <code>usejBox</code>). However, since this is not the case here the dependencies can be attached together with the output.</p>
<p>Finally, the two R functions are “bound” JavaScript-side with an “output binding” that renders the data from the <code>render*</code> function with its <code>*output</code>.</p>
</div>
<div id="discover-lena.js" class="section level2" number="23.2">
<h2><span class="header-section-number">23.2</span> Discover Lena.js</h2>
<p>Let us take a look at an example of lena.js. The library reads the original image and outputs the filtered image in a <code>&lt;canvas&gt;</code>. There are many filters to chose from.</p>
<div class="sourceCode" id="cb459"><pre class="sourceCode html"><code class="sourceCode html"><span id="cb459-1"><a href="lena.html#cb459-1"></a><span class="dt">&lt;!DOCTYPE </span>html<span class="dt">&gt;</span></span>
<span id="cb459-2"><a href="lena.html#cb459-2"></a><span class="kw">&lt;html</span><span class="ot"> xmlns=</span><span class="st">&quot;http://www.w3.org/1999/xhtml&quot;</span><span class="ot"> lang=</span><span class="st">&quot;&quot;</span><span class="ot"> xml:lang=</span><span class="st">&quot;&quot;</span><span class="kw">&gt;</span></span>
<span id="cb459-3"><a href="lena.html#cb459-3"></a></span>
<span id="cb459-4"><a href="lena.html#cb459-4"></a><span class="kw">&lt;head&gt;</span></span>
<span id="cb459-5"><a href="lena.html#cb459-5"></a>  <span class="co">&lt;!-- Import library --&gt;</span></span>
<span id="cb459-6"><a href="lena.html#cb459-6"></a>  <span class="kw">&lt;script</span><span class="ot"> src=</span><span class="st">&quot;lena.js&quot;</span><span class="kw">&gt;&lt;/script&gt;</span></span>
<span id="cb459-7"><a href="lena.html#cb459-7"></a><span class="kw">&lt;/head&gt;</span></span>
<span id="cb459-8"><a href="lena.html#cb459-8"></a></span>
<span id="cb459-9"><a href="lena.html#cb459-9"></a><span class="kw">&lt;body&gt;</span></span>
<span id="cb459-10"><a href="lena.html#cb459-10"></a>  <span class="co">&lt;!-- Image to apply filter --&gt;</span></span>
<span id="cb459-11"><a href="lena.html#cb459-11"></a>  <span class="kw">&lt;img</span><span class="ot"> id=</span><span class="st">&quot;original-image&quot;</span><span class="ot"> src=</span><span class="st">&quot;./image.png&quot;</span> <span class="kw">/&gt;</span></span>
<span id="cb459-12"><a href="lena.html#cb459-12"></a></span>
<span id="cb459-13"><a href="lena.html#cb459-13"></a>  <span class="co">&lt;!-- div to hold visualisation --&gt;</span></span>
<span id="cb459-14"><a href="lena.html#cb459-14"></a>  <span class="kw">&lt;canvas</span><span class="ot"> id=</span><span class="st">&quot;lena&quot;</span><span class="kw">&gt;&lt;/canvas&gt;</span></span>
<span id="cb459-15"><a href="lena.html#cb459-15"></a></span>
<span id="cb459-16"><a href="lena.html#cb459-16"></a>  <span class="co">&lt;!-- Script to create visualisation --&gt;</span></span>
<span id="cb459-17"><a href="lena.html#cb459-17"></a>  <span class="kw">&lt;script&gt;</span></span>
<span id="cb459-18"><a href="lena.html#cb459-18"></a>    <span class="co">// Get the image</span></span>
<span id="cb459-19"><a href="lena.html#cb459-19"></a>    <span class="kw">var</span> originalImage <span class="op">=</span> <span class="va">document</span>.<span class="at">getElementById</span>(<span class="st">&quot;original-image&quot;</span>)<span class="op">;</span></span>
<span id="cb459-20"><a href="lena.html#cb459-20"></a></span>
<span id="cb459-21"><a href="lena.html#cb459-21"></a>    <span class="co">// The canvas where the processed image will be rendered (With filter)</span></span>
<span id="cb459-22"><a href="lena.html#cb459-22"></a>    <span class="kw">var</span> filteredImageCanvas <span class="op">=</span> <span class="va">document</span>.<span class="at">getElementById</span>(<span class="st">&quot;lena&quot;</span>)<span class="op">;</span></span>
<span id="cb459-23"><a href="lena.html#cb459-23"></a></span>
<span id="cb459-24"><a href="lena.html#cb459-24"></a>    <span class="co">// Filter to apply, in this case the red filter</span></span>
<span id="cb459-25"><a href="lena.html#cb459-25"></a>    <span class="kw">var</span> filter <span class="op">=</span> LenaJS[<span class="st">&quot;invert&quot;</span>]<span class="op">;</span></span>
<span id="cb459-26"><a href="lena.html#cb459-26"></a></span>
<span id="cb459-27"><a href="lena.html#cb459-27"></a>    <span class="co">// Apply the filter</span></span>
<span id="cb459-28"><a href="lena.html#cb459-28"></a>    <span class="va">LenaJS</span>.<span class="at">filterImage</span>(filteredImageCanvas<span class="op">,</span> filter<span class="op">,</span> originalImage)<span class="op">;</span></span>
<span id="cb459-29"><a href="lena.html#cb459-29"></a>  <span class="kw">&lt;/script&gt;</span></span>
<span id="cb459-30"><a href="lena.html#cb459-30"></a><span class="kw">&lt;/body&gt;</span></span>
<span id="cb459-31"><a href="lena.html#cb459-31"></a></span>
<span id="cb459-32"><a href="lena.html#cb459-32"></a><span class="kw">&lt;/html&gt;</span></span></code></pre></div>
<div class="figure">
<img src="images/lena-demo.png" alt="" />
<p class="caption">Demo of lena.js - inverted colors</p>
</div>
<p>Therefore, there should be a <code>lenaOutput</code> function that creates the <code>&lt;canvas&gt;</code>, a <code>renderLena</code> function that sends the output of <code>lena</code> which itself accepts the id of the image to filter as well as the filter to apply. Finally, there will be a “output binding” which will include the JavaScript code included in the <code>&lt;script&gt;</code> tags above.</p>
</div>
<div id="setup" class="section level2" number="23.3">
<h2><span class="header-section-number">23.3</span> Setup</h2>
<p>Start by creating a package called “lena.”</p>
<div class="sourceCode" id="cb460"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb460-1"><a href="lena.html#cb460-1"></a>usethis<span class="op">::</span><span class="kw">create_package</span>(<span class="st">&quot;lena&quot;</span>)</span></code></pre></div>
<p>Then, from the root of the package, create the <code>inst</code> directory and <code>assets</code> subdirectory then download and place the <code>lena.js</code> dependency within it.</p>
<div class="sourceCode" id="cb461"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb461-1"><a href="lena.html#cb461-1"></a><span class="kw">dir.create</span>(<span class="st">&quot;inst/assets&quot;</span>, <span class="dt">recursive =</span> <span class="ot">TRUE</span>)</span>
<span id="cb461-2"><a href="lena.html#cb461-2"></a></span>
<span id="cb461-3"><a href="lena.html#cb461-3"></a>url &lt;-<span class="st"> </span><span class="kw">paste0</span>(</span>
<span id="cb461-4"><a href="lena.html#cb461-4"></a>  <span class="st">&quot;https://raw.githubusercontent.com/davidsonfellipe/&quot;</span>,</span>
<span id="cb461-5"><a href="lena.html#cb461-5"></a>  <span class="st">&quot;lena.js/master/dist/lena.min.js&quot;</span></span>
<span id="cb461-6"><a href="lena.html#cb461-6"></a>)</span>
<span id="cb461-7"><a href="lena.html#cb461-7"></a><span class="kw">download.file</span>(url, <span class="st">&quot;inst/assets/lena.min.js&quot;</span>)</span></code></pre></div>
<p>We also need to create a JavaScript file that will include the custom JavaScript code that will eventually generate the custom output.</p>
<div class="sourceCode" id="cb462"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb462-1"><a href="lena.html#cb462-1"></a><span class="kw">file.create</span>(<span class="st">&quot;inst/assets/custom.js&quot;</span>)</span></code></pre></div>
<p>At this point one should have a package directory looking like the tree below.</p>
<pre><code>.
├── DESCRIPTION
├── NAMESPACE
├── R
├── inst
│   └── assets
│       ├── custom.js
│       └── lena.min.js
└── man</code></pre>
</div>
<div id="output" class="section level2" number="23.4">
<h2><span class="header-section-number">23.4</span> Output</h2>
<p>We can then create the <code>lenaOutput</code> function. This function should return an HTML tag which bears an <code>id</code>, or a <code>data-input-id</code> attribute (more on that later) and a <code>class</code>. This is to be used by the user of the function in Shiny just like any other such outputs. For instance, <code>plotOutput</code> creates a <code>&lt;div&gt;</code> the <code>id</code> of which is actually the <code>id</code> used in the <code>plotOutput</code> function.</p>
<div class="sourceCode" id="cb464"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb464-1"><a href="lena.html#cb464-1"></a><span class="co"># the id is used as id to the element</span></span>
<span id="cb464-2"><a href="lena.html#cb464-2"></a>shiny<span class="op">::</span><span class="kw">plotOutput</span>(<span class="dt">id =</span> <span class="st">&quot;myPlotId&quot;</span>)</span></code></pre></div>
<pre><code>## &lt;div id=&quot;myPlotId&quot; class=&quot;shiny-plot-output&quot; style=&quot;width: 100% ; height: 400px&quot;&gt;&lt;/div&gt;</code></pre>
<p>The <code>class</code> is used JavaScript-side to “find” the outputs in the DOM (document object model) and generate the output. The function <code>lenaOutput</code> could thus be as shown below, the <code>id</code> is passed along to the <code>&lt;canvas&gt;</code> which is created with a <code>lena</code> class that will be used in the output binding to find that element and generate the output within that very canvas.</p>
<div class="sourceCode" id="cb466"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb466-1"><a href="lena.html#cb466-1"></a><span class="co">#&#39; @export</span></span>
<span id="cb466-2"><a href="lena.html#cb466-2"></a>lenaOutput &lt;-<span class="st"> </span><span class="cf">function</span>(id){</span>
<span id="cb466-3"><a href="lena.html#cb466-3"></a>  tags<span class="op">$</span><span class="kw">canvas</span>(<span class="dt">id =</span> id, <span class="dt">class =</span> <span class="st">&quot;lena&quot;</span>)</span>
<span id="cb466-4"><a href="lena.html#cb466-4"></a>}</span></code></pre></div>
<p>The dependencies should be added to the above, since this function must be placed in the UI for anything to work we can have the dependencies piggyback on the output element. This works using the htmltools package. The function <code>htmltools::htmlDependency</code> is used to create a dependency that is then attached with <code>htmltools::attachDependencies</code>. While the former creates an object that shiny can understand and translate into <code>&lt;script&gt;</code> or <code>&lt;style&gt;</code> tags, the former attaches them to the output object and ensures dependencies are not imported multiple times (e.g.: when <code>lenaOutput</code> is used more than once).</p>
<div class="sourceCode" id="cb467"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb467-1"><a href="lena.html#cb467-1"></a><span class="co">#&#39; @export</span></span>
<span id="cb467-2"><a href="lena.html#cb467-2"></a>lenaOutput &lt;-<span class="st"> </span><span class="cf">function</span>(id){</span>
<span id="cb467-3"><a href="lena.html#cb467-3"></a>  el &lt;-<span class="st"> </span>shiny<span class="op">::</span>tags<span class="op">$</span><span class="kw">canvas</span>(<span class="dt">id =</span> id, <span class="dt">class =</span> <span class="st">&quot;lena&quot;</span>)</span>
<span id="cb467-4"><a href="lena.html#cb467-4"></a></span>
<span id="cb467-5"><a href="lena.html#cb467-5"></a>  path &lt;-<span class="st"> </span><span class="kw">system.file</span>(<span class="st">&quot;assets&quot;</span>, <span class="dt">package =</span> <span class="st">&quot;lena&quot;</span>)</span>
<span id="cb467-6"><a href="lena.html#cb467-6"></a></span>
<span id="cb467-7"><a href="lena.html#cb467-7"></a>  deps &lt;-<span class="st"> </span><span class="kw">list</span>(</span>
<span id="cb467-8"><a href="lena.html#cb467-8"></a>    htmltools<span class="op">::</span><span class="kw">htmlDependency</span>(</span>
<span id="cb467-9"><a href="lena.html#cb467-9"></a>      <span class="dt">name =</span> <span class="st">&quot;lena&quot;</span>,</span>
<span id="cb467-10"><a href="lena.html#cb467-10"></a>      <span class="dt">version =</span> <span class="st">&quot;0.2.0&quot;</span>,</span>
<span id="cb467-11"><a href="lena.html#cb467-11"></a>      <span class="dt">src =</span> <span class="kw">c</span>(<span class="dt">file =</span> path),</span>
<span id="cb467-12"><a href="lena.html#cb467-12"></a>      <span class="dt">script =</span> <span class="kw">c</span>(<span class="st">&quot;lena.min.js&quot;</span>, <span class="st">&quot;custom.js&quot;</span>)</span>
<span id="cb467-13"><a href="lena.html#cb467-13"></a>    )</span>
<span id="cb467-14"><a href="lena.html#cb467-14"></a>  )</span>
<span id="cb467-15"><a href="lena.html#cb467-15"></a></span>
<span id="cb467-16"><a href="lena.html#cb467-16"></a>  htmltools<span class="op">::</span><span class="kw">attachDependencies</span>(el, deps)</span>
<span id="cb467-17"><a href="lena.html#cb467-17"></a></span>
<span id="cb467-18"><a href="lena.html#cb467-18"></a>}</span></code></pre></div>
</div>
<div id="render" class="section level2" number="23.5">
<h2><span class="header-section-number">23.5</span> Render</h2>
<p>Onto coding the server-side functions, we first define a function called “lena” which takes two arguments and return them as a list (which will eventually be used in JavaScript). First, the id of the image to apply the filter to and second the name of the filter to apply. Again, were we not creating a custom output we could use <code>session$sendCustomMessage</code> to send that list of options JavaScript directly. Here we do not as it will be indirectly handled by the <code>render</code> function we are creating next.</p>
<div class="sourceCode" id="cb468"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb468-1"><a href="lena.html#cb468-1"></a><span class="co">#&#39; @export</span></span>
<span id="cb468-2"><a href="lena.html#cb468-2"></a>lena &lt;-<span class="st"> </span><span class="cf">function</span>(img_id, <span class="dt">filter =</span> <span class="st">&quot;red&quot;</span>){</span>
<span id="cb468-3"><a href="lena.html#cb468-3"></a>  <span class="kw">list</span>(<span class="dt">img_id =</span> img_id, <span class="dt">filter =</span> filter)</span>
<span id="cb468-4"><a href="lena.html#cb468-4"></a>}</span></code></pre></div>
<p>The function <code>renderLena</code> should accept an expression, like other such <code>render*</code> function. For instance in the example below the <code>renderPlot</code> function does accept an expression which uses, amongst other functions, <code>plot</code>.</p>
<div class="sourceCode" id="cb469"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb469-1"><a href="lena.html#cb469-1"></a>output<span class="op">$</span>myPlot &lt;-<span class="st"> </span><span class="kw">renderPlot</span>({</span>
<span id="cb469-2"><a href="lena.html#cb469-2"></a>  <span class="co"># this is an expression</span></span>
<span id="cb469-3"><a href="lena.html#cb469-3"></a>  cars <span class="op">%&gt;%</span><span class="st"> </span></span>
<span id="cb469-4"><a href="lena.html#cb469-4"></a><span class="st">    </span><span class="kw">head</span>() <span class="op">%&gt;%</span><span class="st"> </span></span>
<span id="cb469-5"><a href="lena.html#cb469-5"></a><span class="st">    </span><span class="kw">plot</span>()</span>
<span id="cb469-6"><a href="lena.html#cb469-6"></a>})</span></code></pre></div>
<p>The function <code>renderLena</code> takes an expression and other arguments that are passed to <code>shiny::exprToFunction</code> this does pretty much what it says on the tin: it returns a function from an expression (unless that expression is a function, in which case it returns the expression). This function must be further wrapped in another as the render function must itself return a function.</p>
<div class="sourceCode" id="cb470"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb470-1"><a href="lena.html#cb470-1"></a><span class="co">#&#39; @export</span></span>
<span id="cb470-2"><a href="lena.html#cb470-2"></a>renderLena &lt;-<span class="st"> </span><span class="cf">function</span>(expr, <span class="dt">env =</span> <span class="kw">parent.frame</span>(), <span class="dt">quoted =</span> <span class="ot">FALSE</span>) {</span>
<span id="cb470-3"><a href="lena.html#cb470-3"></a>  <span class="co"># Convert the expression + environment into a function</span></span>
<span id="cb470-4"><a href="lena.html#cb470-4"></a>  func &lt;-<span class="st"> </span>shiny<span class="op">::</span><span class="kw">exprToFunction</span>(expr, env, quoted)</span>
<span id="cb470-5"><a href="lena.html#cb470-5"></a></span>
<span id="cb470-6"><a href="lena.html#cb470-6"></a>  <span class="cf">function</span>(){</span>
<span id="cb470-7"><a href="lena.html#cb470-7"></a>    <span class="kw">func</span>()</span>
<span id="cb470-8"><a href="lena.html#cb470-8"></a>  }</span>
<span id="cb470-9"><a href="lena.html#cb470-9"></a>}</span></code></pre></div>
<p>This covers all R-related code, what’s yet missing is the JavaScript binding.</p>
</div>
<div id="javascript-binding" class="section level2" number="23.6">
<h2><span class="header-section-number">23.6</span> JavaScript Binding</h2>
<p>Here we create an “output binding,” it tells Shiny how to find the component and how to interact with it. An output binding is initialised from <code>Shiny.OutputBinding</code>. Below we initialise a new binding.</p>
<div class="sourceCode" id="cb471"><pre class="sourceCode js"><code class="sourceCode javascript"><span id="cb471-1"><a href="lena.html#cb471-1"></a><span class="co">// custom.js</span></span>
<span id="cb471-2"><a href="lena.html#cb471-2"></a><span class="kw">var</span> lenaBinding <span class="op">=</span> <span class="kw">new</span> <span class="va">Shiny</span>.<span class="at">OutputBinding</span>()<span class="op">;</span></span></code></pre></div>
<p>Then, this must be “extended” by specifying a number of methods, a very necessary one being <code>find</code>. The first is used to look for the output HTML element in the document (<code>scope</code>), and return them as an array (<code>HTMLcollection</code>). Other methods all take an el argument; that value will always be an element that was returned from <code>find</code>. A very straightforward way to accomplish this is to use jQuery’s find method to identify elements with the <code>lena</code> class used in <code>lenaOutput</code>. You are by no means forced to use a CSS class to identify the elements but there is no reason not to.</p>
<div class="sourceCode" id="cb472"><pre class="sourceCode js"><code class="sourceCode javascript"><span id="cb472-1"><a href="lena.html#cb472-1"></a><span class="co">// custom.js</span></span>
<span id="cb472-2"><a href="lena.html#cb472-2"></a><span class="kw">var</span> lenaBinding <span class="op">=</span> <span class="kw">new</span> <span class="va">Shiny</span>.<span class="at">OutputBinding</span>()<span class="op">;</span></span>
<span id="cb472-3"><a href="lena.html#cb472-3"></a></span>
<span id="cb472-4"><a href="lena.html#cb472-4"></a><span class="va">$</span>.<span class="at">extend</span>(lenaBinding<span class="op">,</span> <span class="op">{</span></span>
<span id="cb472-5"><a href="lena.html#cb472-5"></a>  <span class="dt">find</span><span class="op">:</span> <span class="kw">function</span>(scope) <span class="op">{</span></span>
<span id="cb472-6"><a href="lena.html#cb472-6"></a>    <span class="cf">return</span> <span class="at">$</span>(scope).<span class="at">find</span>(<span class="st">&quot;.lena&quot;</span>)<span class="op">;</span></span>
<span id="cb472-7"><a href="lena.html#cb472-7"></a>  <span class="op">}</span></span>
<span id="cb472-8"><a href="lena.html#cb472-8"></a><span class="op">}</span>)<span class="op">;</span></span></code></pre></div>
<p>One might then want to use the <code>getId</code>, a method to return the <code>id</code> of the element, by default, as can be seen in the <a href="https://github.com/rstudio/shiny/blob/master/srcjs/output_binding.js">source code</a> (below), shiny looks for the id as the <code>data-input-id</code> attribute and if that is not found it looks for the element’s <code>id</code>.</p>
<div class="sourceCode" id="cb473"><pre class="sourceCode js"><code class="sourceCode javascript"><span id="cb473-1"><a href="lena.html#cb473-1"></a><span class="co">// getId default</span></span>
<span id="cb473-2"><a href="lena.html#cb473-2"></a><span class="kw">this</span>.<span class="at">getId</span> <span class="op">=</span> <span class="kw">function</span>(el) <span class="op">{</span></span>
<span id="cb473-3"><a href="lena.html#cb473-3"></a>  <span class="cf">return</span> el[<span class="st">&#39;data-input-id&#39;</span>] <span class="op">||</span> <span class="va">el</span>.<span class="at">id</span><span class="op">;</span></span>
<span id="cb473-4"><a href="lena.html#cb473-4"></a><span class="op">}</span></span></code></pre></div>
<p>Since we use the element id the default will work and this can be skipped entirely. Next, one needs to implement the <code>renderValue</code> function which is the very function that generates the output based on data used in <code>lena</code> and sent to the front-end with <code>renderLena</code>. The <code>renderValue</code> accepts two arguments, first <code>el</code> the element where the output should be generated, this is effectively the output of <code>lenaOutput</code> which the binding found using <code>find</code> and <code>getId</code>. Second, <code>data</code>, this is the output of <code>lena</code> sent by <code>renderLena</code>.</p>
<div class="sourceCode" id="cb474"><pre class="sourceCode js"><code class="sourceCode javascript"><span id="cb474-1"><a href="lena.html#cb474-1"></a><span class="co">// custom.js</span></span>
<span id="cb474-2"><a href="lena.html#cb474-2"></a><span class="kw">var</span> lenaBinding <span class="op">=</span> <span class="kw">new</span> <span class="va">Shiny</span>.<span class="at">OutputBinding</span>()<span class="op">;</span></span>
<span id="cb474-3"><a href="lena.html#cb474-3"></a></span>
<span id="cb474-4"><a href="lena.html#cb474-4"></a><span class="va">$</span>.<span class="at">extend</span>(lenaBinding<span class="op">,</span> <span class="op">{</span></span>
<span id="cb474-5"><a href="lena.html#cb474-5"></a>  <span class="dt">find</span><span class="op">:</span> <span class="kw">function</span>(scope) <span class="op">{</span></span>
<span id="cb474-6"><a href="lena.html#cb474-6"></a>    <span class="cf">return</span> <span class="at">$</span>(scope).<span class="at">find</span>(<span class="st">&quot;.lena&quot;</span>)<span class="op">;</span></span>
<span id="cb474-7"><a href="lena.html#cb474-7"></a>  <span class="op">},</span></span>
<span id="cb474-8"><a href="lena.html#cb474-8"></a>  <span class="dt">renderValue</span><span class="op">:</span> <span class="kw">function</span>(el<span class="op">,</span> data) <span class="op">{</span></span>
<span id="cb474-9"><a href="lena.html#cb474-9"></a></span>
<span id="cb474-10"><a href="lena.html#cb474-10"></a>    <span class="at">$</span>(document).<span class="at">ready</span>(<span class="kw">function</span>()<span class="op">{</span></span>
<span id="cb474-11"><a href="lena.html#cb474-11"></a>      <span class="co">// Get the image</span></span>
<span id="cb474-12"><a href="lena.html#cb474-12"></a>      <span class="kw">var</span> originalImage <span class="op">=</span> <span class="va">document</span>.<span class="at">getElementById</span>(<span class="va">data</span>.<span class="at">img_id</span>)<span class="op">;</span></span>
<span id="cb474-13"><a href="lena.html#cb474-13"></a></span>
<span id="cb474-14"><a href="lena.html#cb474-14"></a>      <span class="co">// Filter to apply, in this case the red filter</span></span>
<span id="cb474-15"><a href="lena.html#cb474-15"></a>      <span class="kw">var</span> filter <span class="op">=</span> LenaJS[<span class="va">data</span>.<span class="at">filter</span>]<span class="op">;</span></span>
<span id="cb474-16"><a href="lena.html#cb474-16"></a></span>
<span id="cb474-17"><a href="lena.html#cb474-17"></a>      <span class="co">// Apply the filter</span></span>
<span id="cb474-18"><a href="lena.html#cb474-18"></a>      <span class="va">LenaJS</span>.<span class="at">filterImage</span>(el<span class="op">,</span> filter<span class="op">,</span> originalImage)<span class="op">;</span></span>
<span id="cb474-19"><a href="lena.html#cb474-19"></a>    <span class="op">}</span>)<span class="op">;</span></span>
<span id="cb474-20"><a href="lena.html#cb474-20"></a>  </span>
<span id="cb474-21"><a href="lena.html#cb474-21"></a>  <span class="op">}</span></span>
<span id="cb474-22"><a href="lena.html#cb474-22"></a><span class="op">}</span>)<span class="op">;</span></span></code></pre></div>
<p>Finally, the output binding is registered with shiny. Note that it uses a unique string identifier, the <a href="https://shiny.rstudio.com/articles/building-outputs.html">documentation</a> states:</p>
<blockquote>
<p>At the moment it is unused but future features may depend on it.</p>
</blockquote>
<div class="sourceCode" id="cb475"><pre class="sourceCode js"><code class="sourceCode javascript"><span id="cb475-1"><a href="lena.html#cb475-1"></a><span class="co">// custom.js</span></span>
<span id="cb475-2"><a href="lena.html#cb475-2"></a><span class="kw">var</span> lenaBinding <span class="op">=</span> <span class="kw">new</span> <span class="va">Shiny</span>.<span class="at">OutputBinding</span>()<span class="op">;</span></span>
<span id="cb475-3"><a href="lena.html#cb475-3"></a></span>
<span id="cb475-4"><a href="lena.html#cb475-4"></a><span class="va">$</span>.<span class="at">extend</span>(lenaBinding<span class="op">,</span> <span class="op">{</span></span>
<span id="cb475-5"><a href="lena.html#cb475-5"></a>  <span class="dt">find</span><span class="op">:</span> <span class="kw">function</span>(scope) <span class="op">{</span></span>
<span id="cb475-6"><a href="lena.html#cb475-6"></a>    <span class="cf">return</span> <span class="at">$</span>(scope).<span class="at">find</span>(<span class="st">&quot;.lena&quot;</span>)<span class="op">;</span></span>
<span id="cb475-7"><a href="lena.html#cb475-7"></a>  <span class="op">},</span></span>
<span id="cb475-8"><a href="lena.html#cb475-8"></a>  <span class="dt">renderValue</span><span class="op">:</span> <span class="kw">function</span>(el<span class="op">,</span> data) <span class="op">{</span></span>
<span id="cb475-9"><a href="lena.html#cb475-9"></a></span>
<span id="cb475-10"><a href="lena.html#cb475-10"></a>    <span class="at">$</span>(document).<span class="at">ready</span>(<span class="kw">function</span>()<span class="op">{</span></span>
<span id="cb475-11"><a href="lena.html#cb475-11"></a>      <span class="co">// Get the image</span></span>
<span id="cb475-12"><a href="lena.html#cb475-12"></a>      <span class="kw">var</span> originalImage <span class="op">=</span> <span class="va">document</span>.<span class="at">getElementById</span>(<span class="va">data</span>.<span class="at">img_id</span>)<span class="op">;</span></span>
<span id="cb475-13"><a href="lena.html#cb475-13"></a></span>
<span id="cb475-14"><a href="lena.html#cb475-14"></a>      <span class="co">// Filter to apply, in this case the red filter</span></span>
<span id="cb475-15"><a href="lena.html#cb475-15"></a>      <span class="kw">var</span> filter <span class="op">=</span> LenaJS[<span class="va">data</span>.<span class="at">filter</span>]<span class="op">;</span></span>
<span id="cb475-16"><a href="lena.html#cb475-16"></a></span>
<span id="cb475-17"><a href="lena.html#cb475-17"></a>      <span class="co">// Apply the filter</span></span>
<span id="cb475-18"><a href="lena.html#cb475-18"></a>      <span class="va">LenaJS</span>.<span class="at">filterImage</span>(el<span class="op">,</span> filter<span class="op">,</span> originalImage)<span class="op">;</span></span>
<span id="cb475-19"><a href="lena.html#cb475-19"></a>    <span class="op">}</span>)<span class="op">;</span></span>
<span id="cb475-20"><a href="lena.html#cb475-20"></a>  </span>
<span id="cb475-21"><a href="lena.html#cb475-21"></a>  <span class="op">}</span></span>
<span id="cb475-22"><a href="lena.html#cb475-22"></a><span class="op">}</span>)<span class="op">;</span></span>
<span id="cb475-23"><a href="lena.html#cb475-23"></a></span>
<span id="cb475-24"><a href="lena.html#cb475-24"></a><span class="va">Shiny</span>.<span class="va">outputBindings</span>.<span class="at">register</span>(lenaBinding<span class="op">,</span> <span class="st">&quot;lenaPackage.lenaBinding&quot;</span>)<span class="op">;</span></span></code></pre></div>
<p>Ensure that string uniquely identifies the binding to avoid future clash with other such bindings.</p>
</div>
<div id="test" class="section level2" number="23.7">
<h2><span class="header-section-number">23.7</span> Test</h2>
<p>In order to test the package, an image needs to be downloaded in order to test it otherwise a Cross-Origin Resource Sharing (CORS) error will occur. Below we create a directory for the static files and download the R logo to test lena.</p>
<div class="sourceCode" id="cb476"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb476-1"><a href="lena.html#cb476-1"></a><span class="kw">dir.create</span>(<span class="st">&quot;www&quot;</span>)</span>
<span id="cb476-2"><a href="lena.html#cb476-2"></a><span class="kw">download.file</span>(<span class="st">&quot;https://www.r-project.org/Rlogo.png&quot;</span>, <span class="st">&quot;www/r-logo.png&quot;</span>)</span></code></pre></div>
<p>After running <code>devtools::document</code> and <code>devtools::install</code> one is ready to test the package.</p>
<div class="sourceCode" id="cb477"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb477-1"><a href="lena.html#cb477-1"></a><span class="kw">library</span>(lena)</span>
<span id="cb477-2"><a href="lena.html#cb477-2"></a><span class="kw">library</span>(shiny)</span>
<span id="cb477-3"><a href="lena.html#cb477-3"></a></span>
<span id="cb477-4"><a href="lena.html#cb477-4"></a><span class="co"># serve static files</span></span>
<span id="cb477-5"><a href="lena.html#cb477-5"></a>shiny<span class="op">::</span><span class="kw">addResourcePath</span>(<span class="st">&quot;www&quot;</span>, <span class="st">&quot;www&quot;</span>)</span>
<span id="cb477-6"><a href="lena.html#cb477-6"></a></span>
<span id="cb477-7"><a href="lena.html#cb477-7"></a>ui &lt;-<span class="st"> </span><span class="kw">fluidPage</span>(</span>
<span id="cb477-8"><a href="lena.html#cb477-8"></a>  <span class="co"># original logo</span></span>
<span id="cb477-9"><a href="lena.html#cb477-9"></a>  tags<span class="op">$</span><span class="kw">img</span>(<span class="dt">src =</span> <span class="st">&quot;www/r-logo.png&quot;</span>, <span class="dt">id =</span> <span class="st">&quot;r-logo&quot;</span>),</span>
<span id="cb477-10"><a href="lena.html#cb477-10"></a>  <span class="co"># custom output</span></span>
<span id="cb477-11"><a href="lena.html#cb477-11"></a>  <span class="kw">lenaOutput</span>(<span class="st">&quot;filtered&quot;</span>)</span>
<span id="cb477-12"><a href="lena.html#cb477-12"></a>)</span>
<span id="cb477-13"><a href="lena.html#cb477-13"></a></span>
<span id="cb477-14"><a href="lena.html#cb477-14"></a>server &lt;-<span class="st"> </span><span class="cf">function</span>(input, output){</span>
<span id="cb477-15"><a href="lena.html#cb477-15"></a></span>
<span id="cb477-16"><a href="lena.html#cb477-16"></a>  output<span class="op">$</span>filtered &lt;-<span class="st"> </span><span class="kw">renderLena</span>({</span>
<span id="cb477-17"><a href="lena.html#cb477-17"></a>    <span class="kw">lena</span>(<span class="dt">img_id =</span> <span class="st">&quot;r-logo&quot;</span>, <span class="dt">filter =</span> <span class="st">&quot;invert&quot;</span>)</span>
<span id="cb477-18"><a href="lena.html#cb477-18"></a>  })</span>
<span id="cb477-19"><a href="lena.html#cb477-19"></a></span>
<span id="cb477-20"><a href="lena.html#cb477-20"></a>}</span>
<span id="cb477-21"><a href="lena.html#cb477-21"></a></span>
<span id="cb477-22"><a href="lena.html#cb477-22"></a><span class="kw">shinyApp</span>(ui, server)</span></code></pre></div>
<div class="figure">
<img src="images/lena-test.png" alt="" />
<p class="caption">Lena test with R logo</p>
</div>
<p>As mentioned at the start of this chapter, this was really intended as a learning experience. There are great limitations to the package created, namely it cannot be used outside of shiny (when it should). As will be demonstrated in the following chapters, using htmlwidgets with lena would be far easier.</p>

</div>
</div>



            </section>

          </div>
        </div>
      </div>
<a href="machine-learning.html" class="navigation navigation-prev " aria-label="Previous page"><i class="fa fa-angle-left"></i></a>
<a href="conclusion.html" class="navigation navigation-next " aria-label="Next page"><i class="fa fa-angle-right"></i></a>
    </div>
  </div>
<script src="libs/gitbook/js/app.min.js"></script>
<script src="libs/gitbook/js/lunr.js"></script>
<script src="libs/gitbook/js/clipboard.min.js"></script>
<script src="libs/gitbook/js/plugin-search.js"></script>
<script src="libs/gitbook/js/plugin-sharing.js"></script>
<script src="libs/gitbook/js/plugin-fontsettings.js"></script>
<script src="libs/gitbook/js/plugin-bookdown.js"></script>
<script src="libs/gitbook/js/jquery.highlight.js"></script>
<script src="libs/gitbook/js/plugin-clipboard.js"></script>
<script>
gitbook.require(["gitbook"], function(gitbook) {
gitbook.start({
"sharing": {
"github": true,
"facebook": false,
"twitter": false,
"linkedin": false,
"weibo": false,
"instapaper": false,
"vk": false,
"all": {}
},
"fontsettings": {
"theme": "white",
"family": "sans",
"size": 2
},
"edit": {
"link": "https://github.com/JohnCoene/javascript-for-r/edit/master/7-35-examples-lena.Rmd",
"text": "Edit"
},
"history": {
"link": null,
"text": null
},
"view": {
"link": null,
"text": null
},
"download": {},
"toc": {
"collapse": "section"
}
});
});
</script>

</body>

</html>
